// TODO: remove and replace this file header comment
// This is a .cpp file you will edit and turn in.
// Remove starter comments and add your own
// comments on each function and on complex code sections.
#include <iostream>    // for cout, endl
#include <string>      // for string class
#include "voting.h"
#include "testing/SimpleTest.h"
using namespace std;

int sumOfBlocks(Vector<int>& blocks) {
    int result = 0;
    for (const int& block : blocks) {
        result += block;
    }
    return result;
}

bool isCritical(int votes, int currentBlockVote, int sumOfBlockCount) {
    int temp = sumOfBlockCount / 2;
    return votes <= temp && votes + currentBlockVote > temp;
}

void computePowerIndexesHelper(Vector<int>& remaining, int currentBlockIndex, int currentBlockVote,
                               int votes, Vector<int>& criticalVotes, int sumOfBlockCount, int index)
{
    if (votes > sumOfBlockCount / 2) {
        return;
    }
    if (index == remaining.size()) {
        if (isCritical(votes, currentBlockVote, sumOfBlockCount)) {
            criticalVotes[currentBlockIndex] += 1;
        }
        return;
    }
    computePowerIndexesHelper(remaining, currentBlockIndex, currentBlockVote, votes, criticalVotes, sumOfBlockCount, index + 1);
    computePowerIndexesHelper(remaining, currentBlockIndex, currentBlockVote, votes + remaining[index], criticalVotes, sumOfBlockCount, index + 1);

}

// TODO: Add a function header comment here to explain the
// behavior of the function and how you implemented this behavior
Vector<int> computePowerIndexes(Vector<int>& blocks)
{
    Vector<int> result;
    Vector<int> criticalVotes(blocks.size(), 0);
    int sumOfBlockCount = sumOfBlocks(blocks);
    for (int i = 0; i < blocks.size(); i++) {
        int currentBlockVote = blocks[i];
        blocks.remove(i);
        int votes = 0, index = 0;
        computePowerIndexesHelper(blocks, i, currentBlockVote, votes, criticalVotes, sumOfBlockCount, index);
        blocks.insert(i, currentBlockVote);
    }
    int sumOfCriticalVotes = sumOfBlocks(criticalVotes);
    for (int vote : criticalVotes) {
        int powerIndex = 100 * vote / sumOfCriticalVotes;
        result.add(powerIndex);
    }
    return result;
}

/* * * * * * Test Cases * * * * * */

PROVIDED_TEST("Test power index, blocks 50-49-1") {
    Vector<int> blocks = {50, 49, 1};
    Vector<int> expected = {60, 20, 20};
    EXPECT_EQUAL(computePowerIndexes(blocks), expected);
}

PROVIDED_TEST("Test power index, blocks Hempshead 1-1-3-7-9-9") {
    Vector<int> blocks = {1, 1, 3, 7, 9, 9};
    Vector<int> expected = {0, 0, 0, 33, 33, 33};
    EXPECT_EQUAL(computePowerIndexes(blocks), expected);
}

PROVIDED_TEST("Test power index, blocks CA-TX-NY 55-38-39") {
    Vector<int> blocks = {55, 38, 29};
    Vector<int> expected = {33, 33, 33};
    EXPECT_EQUAL(computePowerIndexes(blocks), expected);
}

PROVIDED_TEST("Test power index, blocks CA-TX-GA 55-38-16") {
    Vector<int> blocks = {55, 38, 16};
    Vector<int> expected = {100, 0, 0};
    EXPECT_EQUAL(computePowerIndexes(blocks), expected);
}

PROVIDED_TEST("Test power index, blocks EU post-Nice") {
    // Estonia is one of those 4s!!
    Vector<int> blocks = {29,29,29,29,27,27,14,13,12,12,12,12,12,10,10,10,7,7,7,7,7,4,4,4,4,4,3};
    Vector<int> expected = {8, 8, 8, 8, 7, 7, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0};
    EXPECT_EQUAL(computePowerIndexes(blocks), expected);
}

PROVIDED_TEST("Time power index operation") {
    Vector<int> blocks;
    for (int i = 0; i < 15; i++) {
        blocks.add(randomInteger(1, 10));
    }
    TIME_OPERATION(blocks.size(), computePowerIndexes(blocks));
}


